﻿/*----------------------------------------------------------------
//  <copyright file="MasterSlaveSplitPolicy.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2022-11-15 13:22</last-date>
//----------------------------------------------------------------*/

namespace MicroCloud.Entity.Internal
{
    #region "主从分离策略"
    /// <summary>
    /// 主从分离策略
    /// </summary>
    internal class MasterSlaveSplitPolicy : IMasterSlaveSplitPolicy
    {
        //字段
        private readonly IUnitOfWork _unitOfWork;
        private readonly ScopedDictionary _scopedDict;

        #region "构造函数"
        #region "初始化一个<see cref="MasterSlaveSplitPolicy"/>类型的新实例"
        /// <summary>
        /// 初始化一个<see cref="MasterSlaveSplitPolicy"/>类型的新实例
        /// </summary>
        /// <param name="provider">服务提供商</param>
        public MasterSlaveSplitPolicy(IServiceProvider provider)
        {
            _unitOfWork = provider.GetUnitOfWork(false);
            _scopedDict = provider.GetRequiredService<ScopedDictionary>();
        }
        #endregion

        #endregion

        #region "方法"
        #region "是否前往从数据库"
        /// <summary>
        /// 是否前往从数据库
        /// </summary>
        /// <param name="options">数据上下文选项</param>
        /// <returns></returns>
        public bool IsToSlaveDatabase(DbContextOption options)
        {
            SlaveDatabaseInfo[] slaveDatabases = options.SlaveDatabase?.SlaveDatabases;
            if (slaveDatabases.IsNullOrEmpty())
            {
                return false;
            }

            //允许工作单元事务，走主库
            if (_unitOfWork.IsEnabledTransaction)
            {
                return false;
            }

            // 在Function显式配置走从库，才走从库
            IFunction function = _scopedDict.Function;
            if (function == null || !function.IsSlaveDatabase)
            {
                return false;
            }

            return true;
        }
        #endregion

        #endregion

    }
    #endregion

}
